package im

import (
	"context"
	"database/sql"
	"encoding/json"
	"fmt"
	"github.com/zeromicro/go-zero/core/logx"
	"time"
	"wave-service/server/app/chat"
	"wave-service/server/app/internal/svc"
	"wave-service/server/app/models"
)

func SaveMessage(msg chat.Message, ctx context.Context, svcCtx *svc.ServiceContext) {
	go func() {
		time.Sleep(time.Second * 1)
		user, err := svcCtx.VisitorsModel.FindOneByUuid(ctx, msg.UserUuid)
		if err != nil {
			logx.Errorf("发送消息回调错误，未找到对应用户 %v", err.Error())
			return
		}
		content := sql.NullString{
			String: msg.Content,
			Valid:  true,
		}
		message := models.CusMessages{
			CreatedAt: time.Now(),
			UpdatedAt: time.Now(),
			ChannelId: msg.ChannelId,
			VisitorId: user.Id,
			Tp:        int64(msg.Type),
			Content:   content,
		}
		if user.AdminId == 0 && msg.Type == 6 {
			message.IsRead = 1
		}
		_, err = svcCtx.MessagesModel.Insert(ctx, &message)
		if err != nil {
			logx.Errorf("存储消息失败%v", err.Error())
		}
		// type = 6 问问题，自动回答问题
		if user.AdminId == 0 && msg.Type == chat.TYPE_ASK_QUESTION {
			reply, err := svcCtx.RepliesModel.FindOneByQuestion(ctx, msg.Content)
			if err != nil {
				logx.Errorf("获得问题答案失败%v", err.Error())
			}
			sendTime := time.Now().Format("2006-01-02 15:04:05")
			var rType uint8
			rType = chat.TYPE_AUTO_REPLY_QUESTION

			if reply.Img != "" {
				reply.Content.String = fmt.Sprintf("%v<br><img src='%v' width='200px'/>", reply.Content.String, reply.Img)
			}

			visitorReply := chat.Message{
				Cmd:        chat.CMD_MSG,
				ChannelId:  msg.ChannelId,
				UserUuid:   msg.UserUuid,
				ToUserUuid: msg.UserUuid,
				Type:       rType,
				Content:    reply.Content.String,
				SendTime:   sendTime,
			}
			chat.SendMessageContentToUuid(msg.UserUuid, visitorReply)

			custcareReply := chat.Message{
				Cmd:        chat.CMD_MSG,
				ChannelId:  msg.ChannelId,
				UserUuid:   msg.ToUserUuid,
				ToUserUuid: msg.ToUserUuid,
				Type:       rType,
				Content:    reply.Content.String,
				SendTime:   sendTime,
			}
			chat.SendMessageContentToUuid(msg.ToUserUuid, custcareReply)
			custcare, err := svcCtx.VisitorsModel.FindOneByUuid(ctx, msg.ToUserUuid)
			if err != nil {
				logx.Errorf("自动回复消息错误，未找到对应用户 %v", err.Error())
				return
			}
			custcareMsg := models.CusMessages{
				CreatedAt: time.Now(),
				UpdatedAt: time.Now(),
				ChannelId: msg.ChannelId,
				VisitorId: custcare.Id,
				Tp:        int64(rType),
				Content:   reply.Content,
				IsRead:    1,
			}
			_, err = svcCtx.MessagesModel.Insert(ctx, &custcareMsg)
			if err != nil {
				logx.Errorf("自动回复存储消息失败%v", err.Error())
			}
		}
	}()

}

func SaveDelayMessage(msg chat.Message, ctx context.Context, svcCtx *svc.ServiceContext) {
	go func() {
		time.Sleep(time.Second * 1)
		sendUser, err := svcCtx.VisitorsModel.FindOneByUuid(ctx, msg.UserUuid)
		if err != nil {
			logx.Errorf("未读队列消息获得用户失败%v", err.Error())
			return
		}
		user, err := svcCtx.VisitorsModel.FindOneByUuid(ctx, msg.ToUserUuid)
		if err != nil {
			logx.Errorf("未读队列消息获得To用户失败%v", err.Error())
			return
		}
		msgByte, err := json.Marshal(msg)
		if err != nil {
			logx.Errorf("json未读队列消息失败%v", err.Error())
			return
		}

		content := sql.NullString{
			String: string(msgByte),
			Valid:  true,
		}

		sendQueue := models.CusSendQueues{
			CreatedAt:     time.Now(),
			UpdatedAt:     time.Now(),
			SendVisitorId: sendUser.Id,
			VisitorId:     user.Id,
			Message:       content,
		}
		_, err = svcCtx.SendQueuesModel.Insert(ctx, &sendQueue)
		if err != nil {
			logx.Errorf("存储未读队列消息失败%d", user.Id)
		}
	}()

}

func LoginSuccess(uuid string, ctx context.Context, svcCtx *svc.ServiceContext) {
	go func() {
		time.Sleep(time.Second * 1)
		user, err := svcCtx.VisitorsModel.FindOneByUuid(ctx, uuid)
		if err != nil {
			logx.Errorf("登录成功后回调，获得用户失败%v", err.Error())
			return
		}
		// 改变用户在线状态
		user.Online = 1
		err = svcCtx.VisitorsModel.Update(ctx, user)
		if err != nil {
			logx.Errorf("登录成功后回调，更新用户在线状态失败%v", err.Error())
			return
		}

		// 自动回复消息
		if user.AdminId == 0 {
			listIds, err := svcCtx.Cache.Smembers("cache:cusReplies:set")
			//log.Println("cache:cusReplies=", listIds)
			err, replies := svcCtx.RepliesModel.FirstReplyList(ctx, uuid, listIds)
			if err == nil {
				for _, reply := range replies {
					chat.SendMessageContentToUuid(uuid, reply)
					time.Sleep(time.Second * 1)
				}
			}
		}

		time.Sleep(time.Second * 1)

		// 未读消息
		queues, _ := svcCtx.SendQueuesModel.FindByUserId(ctx, user.Id)
		for _, queue := range queues {
			chat.SendMessageToUuid(uuid, queue.Message.String)
			svcCtx.SendQueuesModel.Delete(ctx, queue.Id)
		}

		if user.AdminId == 0 {
			userContact, ucErr := svcCtx.VisitorContactsModel.FindOneByUserId(ctx, user.Id)
			if ucErr != nil {
				logx.Errorf("登录成功后回调，获得访客专有客服失败%v", err.Error())
				return
			}
			toUser, tuErr := svcCtx.VisitorsModel.FindOne(ctx, userContact.HasId)
			if tuErr != nil {
				logx.Errorf("登录成功后回调，获得访客专有客服信息失败%v", err.Error())
			}
			// 游客上线通知后台
			content := sql.NullString{
				String: "您好！",
				Valid:  true,
			}
			custcareNoticeMsg := models.CusMessages{
				CreatedAt: time.Now(),
				UpdatedAt: time.Now(),
				ChannelId: userContact.ChannelId,
				VisitorId: user.Id,
				Tp:        chat.TYPE_NOTIFY_ONLINE,
				Content:   content,
			}
			_, err = svcCtx.MessagesModel.Insert(ctx, &custcareNoticeMsg)
			if err != nil {
				logx.Errorf("访客存储消息失败%v", err.Error())
			}
			// 通知客服上线啦
			custcareNotice := chat.Message{
				Cmd:        chat.CMD_MSG,
				ChannelId:  userContact.ChannelId,
				UserUuid:   user.Uuid,
				ToUserUuid: toUser.Uuid,
				Type:       chat.TYPE_NOTIFY_ONLINE,
				Content:    content.String,
				SendTime:   time.Now().Format("2006-01-02 15:04:05"),
			}
			chat.SendMessageContentToUuid(toUser.Uuid, custcareNotice)
		}

	}()

}

func LogoutSuccess(uuid string, ctx context.Context, svcCtx *svc.ServiceContext) {
	go func() {
		time.Sleep(time.Second * 1)
		user, err := svcCtx.VisitorsModel.FindOneByUuid(ctx, uuid)
		if err != nil {
			logx.Errorf("退出登录后回调，获得用户失败%v", err.Error())
			return
		}
		// 改变用户在线状态
		user.Online = 0
		err = svcCtx.VisitorsModel.Update(ctx, user)
		if err != nil {
			logx.Errorf("退出登录后回调，更新用户在线状态失败%v", err.Error())
			return
		}
		// 通知客服
		if user.AdminId == 0 {
			userContact, ucErr := svcCtx.VisitorContactsModel.FindOneByUserId(ctx, user.Id)
			if ucErr != nil {
				logx.Errorf("退出登录后回调，获得访客专有客服失败%v", err.Error())
				return
			}
			toUser, tuErr := svcCtx.VisitorsModel.FindOne(ctx, userContact.HasId)
			if tuErr != nil {
				logx.Errorf("退出登录后回调，获得访客专有客服信息失败%v", err.Error())
			}
			// 游客上线通知后台
			content := sql.NullString{
				String: "再见！",
				Valid:  true,
			}
			custcareNoticeMsg := models.CusMessages{
				CreatedAt: time.Now(),
				UpdatedAt: time.Now(),
				ChannelId: userContact.ChannelId,
				VisitorId: user.Id,
				Tp:        chat.TYPE_NOTIFY_OFFLINE,
				Content:   content,
			}
			_, err = svcCtx.MessagesModel.Insert(ctx, &custcareNoticeMsg)
			if err != nil {
				logx.Errorf("访客存储消息失败%v", err.Error())
			}
			// 通知客服下线啦
			custcareNotice := chat.Message{
				Cmd:        chat.CMD_MSG,
				ChannelId:  userContact.ChannelId,
				UserUuid:   user.Uuid,
				ToUserUuid: toUser.Uuid,
				Type:       chat.TYPE_NOTIFY_OFFLINE,
				Content:    content.String,
				SendTime:   time.Now().Format("2006-01-02 15:04:05"),
			}
			chat.SendMessageContentToUuid(toUser.Uuid, custcareNotice)
		}

	}()
}
